package jk.spider.core.impl;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import jk.spider.core.event.URLFound.URLFound;
import jk.spider.util.ParserUtil;
import jk.spider.util.config.ConfigConstants;
import jk.spider.util.config.MappedPropertySet;
import jk.spider.util.config.PropertySet;

import org.apache.log4j.Logger;

public class URLFindFactory {
	private static final Logger log = Logger.getLogger(URLFindFactory.class);
	public URLFound[] createURLFound(PropertySet props) {
		List<URLFound> loadedFound = new ArrayList<URLFound>();
		PropertySet foundProps = new MappedPropertySet(ConfigConstants.CONFIG_URL, props);
		int foundCount = foundProps.getInteger(ConfigConstants.URL_COUNT, 0);
		log.info("Loading " + foundCount + " URLFound.");
		for(int i = 0; i < foundCount; i++) {
			URLFound urlFound = null;
			Class urlFoundClass = foundProps.getClass("" + (i+1) + "." + ConfigConstants.URL_CLASS, null);
			String urlReg = foundProps.getString("" + (i+1) + "." + ConfigConstants.URL_REG, "");
			log.info("Loading URLFound configuration '" + urlFoundClass.getName() + "'...");
			
			String urlFilter = foundProps.getString("" + (i+1) + "." + ConfigConstants.URL_FILTER, "");
			Set<String> urlFilterSet = this.getFilterSet(urlFilter);
			Class[] paramClasses = null;
			Object[] params = null;
			 
			if(urlFilterSet == null) {
				paramClasses = new Class[1];
				paramClasses[0] = String.class;
				params = new Object[1];
				params[0] = urlReg;
			} else {
				paramClasses = new Class[2];
				paramClasses[0] = String.class;
				paramClasses[1] = Set.class;
				params = new Object[2];
				params[0] = urlReg;
				params[1] = urlFilterSet;
			}
           
			if(urlFoundClass != null) {
				try {
					Constructor constructor = urlFoundClass.getDeclaredConstructor(paramClasses);
					urlFound = (URLFound) constructor.newInstance(params);
				} catch (InstantiationException e) {
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					e.printStackTrace();
				} catch (NoSuchMethodException e) {
					e.printStackTrace();
				} catch (InvocationTargetException e) {
					e.printStackTrace();
				}
			}
			loadedFound.add(urlFound);
		}
		log.info("Loaded " + loadedFound.size() + " URLFound.");
		return (URLFound[]) loadedFound.toArray(new URLFound[loadedFound.size()]);
	}
	
	private Set<String> getFilterSet(String urlFilter) {
		if(ParserUtil.isStringNull(urlFilter))
			return null;
		
		String [] urlFilters = urlFilter.split("\\|");
		if(urlFilters.length == 0)
			return null;
		
		Set<String> urlFilterSet = new HashSet<String>();
		for(String filter : urlFilters)
			urlFilterSet.add(filter.toLowerCase());
		return urlFilterSet;
	}
}
